package com.cloudfun.campusshare.device.protocol.handler;

import com.alibaba.fastjson.JSONObject;
import com.cloudfun.campusshare.common.constant.*;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.device.protocol.AliyunIotMsgSender;
import com.cloudfun.campusshare.device.protocol.command.CommandFactory;
import com.cloudfun.campusshare.entity.DeviceEntity;
import com.cloudfun.campusshare.repo.DeviceEntityRepo;
import com.cloudfun.campusshare.sender.DelayMessage;
import com.cloudfun.campusshare.sender.DelayTaskMessageSender;
import com.cloudfun.campusshare.service.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.stereotype.Component;

import javax.jms.JMSException;
import javax.jms.Message;

/**
 * Created by Huqin on 2020/3/25
 */
@Slf4j
@Component
public class AliyunIotDeviceStatusHandler implements AliyunIotMsgHandler {

    @Autowired
    private DeviceEntityRepo deviceEntityRepo;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private AliyunIotMsgSender aliyunIotMsgSender;

    @Autowired
    private DelayTaskMessageSender delayTaskMessageSender;

    public static final String ONLINE_FLAG = "online";
    public static final String OFFLINE_FLAG = "offline";

    @Override
    public boolean support(Message message) throws JMSException {
        return message.getStringProperty("topic").startsWith("/as/mqtt/status/");
    }

    @Override
    public void handle(Message message) throws JMSException {
        String messageId = message.getStringProperty("messageId");
        boolean processSuccess = false;
        for (int i = 0; i < 5; i++) {
            try {
                this.doHandle(message);
                processSuccess = true;
                break;
            } catch (ObjectOptimisticLockingFailureException oplfe) {
                log.error("4G设备上下线消息id：{}, 处理时乐观锁异常: ", messageId, oplfe);
            }
        }
        if (!processSuccess) {
            throw new BusinessException(Code.ERROR, "乐观锁失败，且超过最大重试次数：" + 5);
        }
    }

    private void doHandle(Message message) throws JMSException {
        String body = new String(message.getBody(byte[].class));
        JSONObject jsonObject = JSONObject.parseObject(body);
        String productKey = jsonObject.getString("productKey");
        String deviceName = jsonObject.getString("deviceName");
        String status = jsonObject.getString("status");
        String generateTime = message.getStringProperty("generateTime");

        deviceService.updateInteractionTime(deviceName, generateTime);

        boolean online = ONLINE_FLAG.equals(status);
        if (online) {
            this.handleStatusChange(true, deviceName, productKey, generateTime);
        } else {
            DeviceEntity deviceEntity = deviceService.findByImei(deviceName);
            if (null == deviceEntity || StringUtils.isBlank(deviceEntity.getAliyunProdKey())) {
                return;
            }
            // 因为阿里云MQTT可能先发Online 后发Offline, 所以收到OFFLINE时需要再查询一下
            DelayMessage delayMessage = DelayMessage.builder()
                    .deviceId(deviceName)
                    .type(DelayMsgType.ALIYUN_DEVICE_STATUS_REGULATE)
                    .build();
            delayTaskMessageSender.sendDelayMessage(delayMessage, 20 * 1000);
        }
    }

    /**
     * 处理设备状态更新
     *
     * @param online
     * @param deviceName
     * @param productKey
     * @param timestamp
     */
    public void handleStatusChange(boolean online, String deviceName, String productKey, String timestamp) {
        DeviceEntity deviceEntity = deviceService.findByImei(deviceName);
        if (null == deviceEntity) {
            // 创建设备
            deviceEntity = DeviceEntity.builder()
                    .imei(deviceName)
                    .machineNo(deviceName)
                    .isUsing(true)
                    .online(true)
                    .status(DeviceStatus.NOT_RUNNING)
                    .moduleStatus(DeviceModuleStatus.NOT_TEST)
                    .deviceType(DeviceType.GXY8.getName())
                    .build();
        }
        if (online) {
            // 查询typeId
            BaseConstant.SCHEDULED_EXECUTOR.execute(() -> aliyunIotMsgSender.send(productKey, deviceName, new CommandFactory().typeIdQuery().toString()));
        }
        // 更新设备状态
        if (StringUtils.isBlank(deviceEntity.getFirstInteractionTime())) {
            deviceEntity.setFirstInteractionTime(timestamp);
        }
        deviceEntity.setLastInteractionTime(timestamp);
        deviceEntity.setAliyunProdKey(productKey);
        deviceEntity.setPlatform(DevicePlatform.ALIYUN_IOT);
        deviceEntity.setOnline(online);
        deviceEntityRepo.save(deviceEntity);
    }

}
